(defun* first (c) (car c))
(defun* second (c) (car (cdr c)))
(defun* third (c) (car (cdr (cdr c))))

(defmacro* defun (name args &rest body)
  `(defun* ,name ,args
     (block ,name
	,@body)))

(defmacro* dotimes (spec &rest body)
  (let ((var (first spec))
	(max (second spec)))
    `(block a
	    (let ((,var 0) (max* ,max))
	      (while*
	       (if (not (< ,var max*))
		   (return-from a t))
	       ,@body
	       (setq ,var (+ 1 ,var)))))))

(setq newline (elt "
" 0))

(defun* write-line (str &optional (s nil))
  (dotimes (i (length str))
    (if s (write-char (elt str i) s)
      (write-char (elt str i))))
  (if s (write-char newline s)
    (write-char newline))
  t)

(defmacro* with-open-file (spec &rest body)
  `(let ((,(car spec) (open* ,(second spec))))
     ,@body
     (close* ,(car spec))))

(defmacro* deftest (name args &rest body)
  `(defun ,name ,args
     (if (block ,name ,@body)
	 (println "OK")
       (println "NG"))))

(deftest test-eq (&rest rest)
  (apply #'eq rest))

